package com.dd.cloud.auth.service.impl;

import com.dd.cloud.auth.contants.RoleConstants;
import com.dd.cloud.auth.entity.AdminRole;
import com.dd.cloud.auth.entity.RoleMenu;
import com.dd.cloud.auth.mapper.RoleMenuMapper;
import com.dd.cloud.auth.service.IAdminPowerService;
import com.dd.cloud.auth.service.IAdminRoleService;
import com.dd.cloud.auth.service.IRoleMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.RedisKeyConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.vo.LoginInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色菜单表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2023-06-01
 */
@Service
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements IRoleMenuService {
    @Autowired
    private IAdminPowerService adminPowerService;
    @Autowired
    private IAdminRoleService adminRoleService;


    /**
     * @description 角色id查询树形菜单
     * @param roleId: 角色id
     * @return List<RoleMenu>
     * @author czg
     * @date 2023/6/1 17:31
    */
    @Override
    public List<RoleMenu> queryMenuTreeByUserId(Integer roleId) {
        if (roleId == null){
            LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
            if (loginInfo == null){
                throw new ZekeException(ZkExceptionEnum.LOGIN_AGAIN);
            }
            roleId = loginInfo.getRoleId();
        }

        AdminRole byId = adminRoleService.getById(roleId);
        List<RoleMenu> list = new ArrayList<>();
        if (byId == null){
            return list;
        }
        if (byId.getAdmin() == RoleConstants.AdminLv.ADMIN) {
            //超级管理员,查全部内容
            list = getBaseMapper().getUserMenuByType(byId.getType());
        } else {
            list = getBaseMapper().getRoleMenuByRoleId(roleId, null);
        }

        List<RoleMenu> roleMenus = toMenuTree(list);
        return roleMenus;
    }

    @Override
    @Cacheable(value = RedisKeyConstants.CacheKey.TREEROLEMENU, key = "#p0")
    public List<RoleMenu> queryMenuByUserId(Integer roleId) {
        AdminRole byId = adminRoleService.getById(roleId);
        List<RoleMenu> list = new ArrayList<>();
        if (byId == null){
            return list;
        }
        if (byId.getAdmin() == RoleConstants.AdminLv.ADMIN) {
            //超级管理员,查全部内容
            list = getBaseMapper().getUserMenuByType(byId.getType());
        } else {
            list = getBaseMapper().getRoleMenuByRoleId(roleId, null);
        }

        return list;
    }

    /**
     * 将list转换树形菜单
     *
     * @param list
     * @return
     */
    public List<RoleMenu> toMenuTree(List<RoleMenu> list) {
        List<RoleMenu> parents = list.stream().filter(item -> item.getPid().equals(0)).collect(Collectors.toList());
        List<RoleMenu> sons = list.stream().filter(item -> !item.getPid().equals(0)).collect(Collectors.toList());
        //集合排序 正序
        parents.sort(Comparator.comparingInt(t -> t.getSort().intValue()));
        parents.forEach(item -> forRoleMenu(item, sons));
        return parents;
    }

    /**
     * 递归下挂菜单
     *
     * @param parent
     * @param sons
     */
    public void forRoleMenu(RoleMenu parent, List<RoleMenu> sons) {
        List<RoleMenu> list = sons.stream()
                .filter(item -> item.getPid().equals(parent.getId()))
                .sorted(Comparator.comparingInt(t -> t.getSort().intValue()))
                .collect(Collectors.toList());
        //集合排序 正序
        list.forEach(item -> {
                    if (parent.getSonMenus() == null) {
                        parent.setSonMenus(new ArrayList<>());
                    }
                    parent.getSonMenus().add(item);
                    forRoleMenu(item, sons);
                }
        );
    }

}
